using System;
using System.Collections.Generic;
using UnityEditor;
using UnityEditor.Experimental.GraphView;
using UnityEngine;
using UnityEngine.UIElements;
using YDExtendTool.Scripts;
using Debug = UnityEngine.Debug;

namespace YDExtendTool.Editor.TreeDataCreator
{
    public class TreeDataCreator : EditorWindow
    {
        public static TreeDataCreator instance;

        public TreeView View;

        public InspectorView Inspector;
        
        public Dictionary<string, TreeNodeView> VisitNodes;

        private TextField _fileSavePath;

        [MenuItem("Window/UI Toolkit/TreeDataCreator _%&i")]
        public static void ShowExample()
        {
            TreeDataCreator wnd = GetWindow<TreeDataCreator>();
            wnd.titleContent = new GUIContent("TreeDataCreator");
        }
        
        public void CreateGUI()
        {
            // Each editor window contains a root VisualElement object
            VisualElement root = rootVisualElement;

            // VisualElements objects can contain other VisualElement following a tree hierarchy.
            // Instantiate UXML
            var visualTree =
                AssetDatabase.LoadAssetAtPath<VisualTreeAsset>("Assets/YDExtendTool/Editor/TreeDataCreator/TreeDataCreator.uxml");
            visualTree.CloneTree(root);

            instance = this;

            View = root.Q<TreeView>();
            Inspector = root.Q<InspectorView>();
            VisitNodes = new Dictionary<string, TreeNodeView>();
            _fileSavePath = root.Q<TextField>("FileSavePath");

            TreeNodeDataBase data = Resources.Load<TreeNodeDataBase>(TreeDataSetting.Instance.EditTreeDataPath);
            if (data && data.RootNode != null)
            {
                Debug.Log($"TreeDataCreator 打开：{data.name}");
                _fileSavePath.value = TreeDataSetting.Instance.EditTreeDataPath;
                View.RootView = CreateTreeView(data.RootNode);
            }
            else
            {
                Debug.Log($"TreeDataCreator::CreateGUI() : 目标路径 {TreeDataSetting.Instance.EditTreeDataPath} 不存在 或 根节点为空");
            }
        }

        private void OnInspectorUpdate()
        {
            View?.FlushView();
        }
        

        TreeNodeView CreateTreeView(TreeNodeBase node)
        {
            if (null == node) return null;
            if (VisitNodes.TryGetValue(node.Guid, out var view)) return view;
            TreeNodeView nodeView = new TreeNodeView(node);
            nodeView.SetPosition(new Rect(node.Position, Vector2.one));
            View.AddElement(nodeView);
            // 避免重复访问同一个节点
            VisitNodes.Add(node.Guid, nodeView);
            // 创建后继节点
            switch (node)
            {
                case TreeNodeMultipleNextBase stnSelect:
                    foreach (var childNodesValue in stnSelect.ChildNodes)
                    {
                        if (null != childNodesValue)
                        {
                            CreateTreeView(childNodesValue);
                        }
                    }

                    break;
            }

            // 连线
            nodeView.LinkLine();
            return nodeView;
        }

        public class RightClickMenu : ScriptableObject, ISearchWindowProvider
        {
            public delegate bool SelectEntryDelegate(SearchTreeEntry searchTreeGroupEntry,
                SearchWindowContext context);

            public SelectEntryDelegate OnSelectEntryHandle;

            public List<SearchTreeEntry> CreateSearchTree(SearchWindowContext context)
            {
                var entries = new List<SearchTreeEntry>();
                // entries.Add(new SearchTreeGroupEntry(new GUIContent("Create Node")));
                var config = TreeDataSetting.Instance.Menu;
                // 根据TreeDataSetting配置 ，创建菜单
                entries = CreateMenuByConfig(entries, config, 0);
                // 创建包含所有树节点的菜单
                entries = AddNodeType(typeof(TreeNodeBase),entries, "全部节点");
                return entries;
            }

            private List<SearchTreeEntry> AddNodeType(Type type, List<SearchTreeEntry> entries, string pathName)
            {
                entries.Add(new SearchTreeGroupEntry(new GUIContent(pathName), 1));
                List<Type> rootNodeTypes = type.GetDerivedClassed();
                foreach (var rootType in rootNodeTypes)
                {
                    string typeName = rootType.Name;
                    entries.Add(new SearchTreeEntry(new GUIContent(typeName)) { level = 2, userData = rootType });
                }

                return entries;
            }

            public bool OnSelectEntry(SearchTreeEntry searchTreeEntry, SearchWindowContext context)
            {
                if (OnSelectEntryHandle == null)
                {
                    return false;
                }

                return OnSelectEntryHandle(searchTreeEntry, context);
            }

            private List<SearchTreeEntry> CreateMenuByConfig(List<SearchTreeEntry> entries, TreeDataMenuConfig config,int level)
            {
                switch (config)
                {
                    case TreeDataMenuFolder folder:
                        entries.Add(new SearchTreeGroupEntry(new GUIContent(folder.Name), level));
                        foreach (var value in folder.MenuConfigs)
                        {
                            CreateMenuByConfig(entries, value, level + 1);
                        }
                        break;
                    case TreeDataMenuFile file:
                        entries.Add(new SearchTreeGroupEntry(new GUIContent(file.Name), level));
                        List<Type> rootNodeTypes = file.DataType.GetDerivedClassed();
                        foreach (var rootType in rootNodeTypes)
                        {
                            string typeName = rootType.Name;
                            entries.Add(new SearchTreeEntry(new GUIContent(typeName)) { level = level+1, userData = rootType });
                        }

                        break;
                }
                return entries;
            }
        }
    }

}
